namespace EyeSoft.Wpf.Facilities
{
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Linq.Expressions;

	using EyeSoft.Reflection;

	internal class DependentProperties
	{
		private readonly Action<string> onPropertyChanged;

		private readonly IList<DependentProperty> dependentProperties =
			new List<DependentProperty>();

		public DependentProperties(Action<string> onPropertyChanged)
		{
			this.onPropertyChanged = onPropertyChanged;
		}

		public DependentProperty Register(Expression<Func<object>> propertyExpression)
		{
			var propertyInfo = propertyExpression.Property();

			var property = propertyInfo.Name;

			if (dependentProperties.Any(x => x.PropertyName == property))
			{
				new ArgumentException("The property {Property} has already specified its dependencies.").Throw();
			}

			var dependentProperty = new DependentProperty(propertyInfo);

			dependentProperties.Add(dependentProperty);

			return dependentProperty;
		}

		public void Refresh(string propertyName)
		{
			var properties =
				dependentProperties.Where(dependentProperty => dependentProperty.HasToRefresh(propertyName));

			foreach (var dependentProperty in properties)
			{
				onPropertyChanged(dependentProperty.PropertyName);
			}
		}
	}
}